home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection 1998 Fall: Game Toolkit / Disc.iso / SDKs / PCI Driver Development Kit / • Tools / Utility / DisplayNameRegistry 950412 / Src / ManageDisplayList.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-27  |  8.2 KB  |  306 lines  |  [TEXT/MPCC]

  1. /*                                    ManageDisplayList.c                            */
  2. /*
  3.  * Copyright © 1993-94 Apple Computer Inc. All rights reserved.
  4.  */
  5. #include "DisplayNameRegistry.h"
  6. pascal short                SortCompareProc(
  7.         void                    *refCon,
  8.         const TwistDownHdl        listElementA,
  9.         const TwistDownHdl        listElementB
  10.     );
  11.     
  12. void                        DrawListElement(
  13.         TwistDownPtr            twistDownPtr,        /* Locked data handle        */
  14.         const Rect                *viewRect,            /* Draw in this area        */
  15.         short                    vIndent
  16.     );
  17. /*
  18.  * Parameters for the print handler.
  19.  */
  20. #define kPrintoutHeaderFont        "\pHelvetica"
  21. #define kPrintoutHeaderFontSize    9
  22. #define kPrintoutHeaderGap        4
  23. #define kPrintoutHeaderStyle    bold
  24.  
  25. /*
  26.  * Sort the registry list on the given criterion. Then, for all elements of the
  27.  * registry list, if the primary sort key changes, build a new display list
  28.  * element, otherwise extend the current display list.
  29.  *        primary (text from sort key)
  30.  *            secondary (text from other string)
  31.  *                contents
  32.  */
  33. void
  34. SortAndDisplayBrowserWindow(
  35.         register BrowserPtr        browserPtr
  36.     )
  37. {
  38.         OSErr                    status;
  39.         TwistDownHdl            registryElement;
  40.         TwistDownSiblingSet        secondarySiblingSet;
  41.         char                    *pathName;
  42.         char                    *oldPrimary;
  43.         char                    *foundProperty;
  44.         Boolean                    newPrimary;
  45.         Ptr                        primaryText;
  46.         unsigned short            primaryTextLength;
  47.         UInt32                    oldRegEntryID;
  48.         UInt32                    newRegEntryID;
  49.         Ptr                        secondaryText;
  50.         unsigned short            secondaryTextLength;
  51.         char                    oneLineWork[kOneLineFormatLength];
  52. #define REG_ELEM    (**registryElement)
  53. #define SEC            (secondarySiblingSet)
  54. #define SEC_ELEM    (**SEC.thisElement)
  55. #define DIS_ELEM    (**DIS.thisElement)
  56.         
  57.         SetCursor(*GetCursor(watchCursor));
  58.         status = SortTwistDownList(
  59.             ®.firstElement,
  60.             SortCompareProc,
  61.             browserPtr
  62.         );
  63.         if (status != noErr)
  64.             NonFatalError(status, "\pNo memory to sort list");
  65.         else {
  66.             InitializeDisplayList(browserPtr);
  67.             oldPrimary = "";
  68.             oldRegEntryID = 0;
  69.             for (status = noErr, registryElement = REG.firstElement;
  70.                     status == noErr && registryElement != NULL;
  71.                     registryElement = REG_ELEM.nextElement) {
  72.                 newRegEntryID = UnpackDataRecord(
  73.                             *registryElement, &pathName, &foundProperty);
  74.                 if (BROWSER.sortByName) {
  75.                     primaryText = (Ptr) pathName;
  76.                     primaryTextLength = strlen(pathName);
  77.                     secondaryText = (Ptr) foundProperty;
  78.                     secondaryTextLength = strlen(foundProperty);
  79.                 }
  80.                 else {
  81.                     primaryText = (Ptr) foundProperty;
  82.                     primaryTextLength = strlen(foundProperty);
  83.                     secondaryText = (Ptr) pathName;
  84.                     secondaryTextLength = strlen(pathName);
  85.                 }
  86.                 newPrimary = (strcmp(oldPrimary, (char *) primaryText) != 0);
  87.                 if (BROWSER.sortByName && newPrimary == FALSE)
  88.                     newPrimary = (newRegEntryID != oldRegEntryID);
  89.                 /*
  90.                  * If this is a new primary element, extend the primary display
  91.                  * list and start a new secondary list for the new primary element.
  92.                  */
  93.                 if (newPrimary) {
  94.                     oldPrimary = (char *) primaryText;
  95.                     oldRegEntryID = newRegEntryID;
  96.                     status = MakeTwistDownSibling(
  97.                                 &DIS,
  98.                                 kPrimaryIndentLevel,
  99.                                 primaryTextLength,
  100.                                 primaryText
  101.                     );
  102.                     NewTwistDownSiblingSet(&SEC);
  103.                 }
  104.                 /*
  105.                  * Store the current secondary element as a member of the current
  106.                  * secondary sibling set. If this is the first member, plug it
  107.                  * into the current primary element.
  108.                  *
  109.                  * But first, try to scrunch one-line values so the secondary
  110.                  * text and its value fit onto a single line.
  111.                  */
  112.                 if (OneLineProperty(
  113.                             (char *) secondaryText,
  114.                             REG_ELEM.subElement,
  115.                             oneLineWork
  116.                         )) {
  117.                     status = MakeTwistDownSibling(        /* One-liner            */
  118.                                 &SEC,
  119.                                 kSecondaryIndentLevel,
  120.                                 strlen(oneLineWork),
  121.                                 (Ptr) oneLineWork
  122.                             );
  123.                 }
  124.                 else {
  125.                     status = MakeTwistDownSibling(        /* Multi-line name        */
  126.                                 &SEC,
  127.                                 kSecondaryIndentLevel,
  128.                                 secondaryTextLength,
  129.                                 secondaryText
  130.                             );
  131.                     if (status == noErr) {                /* Multi-line data        */
  132.                         SEC_ELEM.subElement = REG_ELEM.subElement;
  133.                         if (SEC_ELEM.subElement != NULL)
  134.                             SEC_ELEM.flag |= kHasTwistDown;
  135.                     }
  136.                 }
  137.                 if (status == noErr) {
  138.                     SEC_ELEM.flag |= (REG_ELEM.flag & kUserFlagMask);
  139.                     if (DIS_ELEM.subElement == NULL) {
  140.                         DIS_ELEM.subElement = SEC.firstElement;
  141.                         DIS_ELEM.flag |= kHasTwistDown;
  142.                     }
  143.                 }
  144.             } /* For all registry elements */
  145.             CreateVisibleList(BROWSER.theList, DIS.firstElement);
  146.         }
  147.         InitCursor();
  148. #undef REG_ELEM
  149. #undef SEC
  150. #undef SEC_ELEM
  151. #undef DIS_ELEM
  152. }
  153.  
  154. pascal short
  155. SortCompareProc(
  156.         void                    *refCon,
  157.         const TwistDownHdl        listElementA,
  158.         const TwistDownHdl        listElementB
  159.     )
  160. {
  161.         short                    result;
  162.         char                    *pathNameA;
  163.         char                    *foundPropertyA;
  164.         char                    *pathNameB;
  165.         char                    *foundPropertyB;
  166.         UInt32                    regEntryA;
  167.         UInt32                    regEntryB;
  168. #define browserPtr    ((BrowserPtr) refCon)
  169.  
  170.         regEntryA = UnpackDataRecord(*listElementA, &pathNameA, &foundPropertyA);
  171.         regEntryB = UnpackDataRecord(*listElementB, &pathNameB, &foundPropertyB);
  172.         if (BROWSER.sortByName) {
  173.             result = strcmp(pathNameA, pathNameB);
  174.             if (result == 0) {
  175.                 result = (regEntryA > regEntryB) ? +1
  176.                        : (regEntryA < regEntryB) ? -1
  177.                        : 0;
  178.             }
  179.             if (result == 0)
  180.                 result = strcmp(foundPropertyA, foundPropertyB);
  181.         }
  182.         else {
  183.             result = strcmp(foundPropertyA, foundPropertyB);
  184.             if (result == 0) {
  185.                 result = strcmp(pathNameA, pathNameB);
  186.                 if (result == 0) {
  187.                     result = (regEntryA > regEntryB) ? +1
  188.                            : (regEntryA < regEntryB) ? -1
  189.                            : 0;
  190.                 }
  191.             }
  192.         }
  193.         return (result);
  194. #undef browserPtr
  195. }
  196.  
  197. /*
  198.  * Clean out the current display list. This requires some small amount of care as
  199.  * the value (third-level) list is a direct pointer into the registry list.
  200.  */
  201. void
  202. InitializeDisplayList(
  203.         register BrowserPtr        browserPtr
  204.     )
  205. {
  206.         TwistDownHdl            primaryList;
  207.         TwistDownHdl            secondaryList;
  208. #define PRI    (**primaryList)
  209. #define SEC    (**secondaryList)
  210.  
  211.         for (primaryList = DIS.firstElement;
  212.                 primaryList != NULL;
  213.                 primaryList = PRI.nextElement) {
  214.             for (secondaryList = PRI.subElement;
  215.                     secondaryList != NULL;
  216.                     secondaryList = SEC.nextElement) {
  217.                 SEC.subElement = NULL;
  218.             }
  219.         }
  220.         DisposeTwistDownHdl(DIS.firstElement, NULL, 0);
  221.         NewTwistDownSiblingSet(&DIS);
  222. #undef PRI
  223. #undef SEC
  224. }
  225.  
  226.  
  227. /*
  228.  * This is called to display the current element.
  229.  */
  230. pascal void
  231. DisplayListDrawProc(
  232.         ListHandle                twistDownListHdl,    /* The list itself            */
  233.         TwistDownPtr            twistDownPtr,        /* Locked data handle        */
  234.         const Rect                *viewRect            /* Draw in this area        */
  235.     )
  236. {
  237.         short                    textWidth;
  238.         short                    pictWidth;            /* But, there are two picts    */
  239.         Rect                    pictRect;
  240.         Rect                    textRect;
  241.         Boolean                    isLeftJustify;
  242.         PicHandle                picHandle;
  243.         FontInfo                info;
  244. #define ELEM    (*twistDownPtr)
  245.  
  246.         UNUSED(twistDownListHdl);
  247.         isLeftJustify = (GetSysDirection() == 0);
  248.         pictWidth = CharWidth('M') * 2;                /* Width of one pict        */
  249.         pictRect = *viewRect;                        /* Rect for one pict        */
  250.         if (isLeftJustify)                            /* Left-justify                */
  251.             pictRect.right = pictRect.left + pictWidth;
  252.         else {                                        /* Right-justify            */
  253.             pictRect.left = pictRect.right - pictWidth;
  254.             pictWidth = (-pictWidth);
  255.         }
  256.         GetFontInfo(&info);
  257.         switch (ELEM.indentLevel) {
  258.         case kPrimaryIndentLevel:
  259.             textRect = *viewRect;
  260.             break;
  261.         case kSecondaryIndentLevel:
  262.             /*
  263.              * If only one bit is set, tab over once.
  264.              */
  265.             switch (ELEM.flag & (kSavedInNVRAM | kSavedOnDisk)) {
  266.             case 0:
  267.                 OffsetRect(&pictRect, pictWidth * 2, 0);
  268.                 break;
  269.             case kSavedInNVRAM:
  270.             case kSavedOnDisk:
  271.                 OffsetRect(&pictRect, pictWidth, 0);
  272.                 break;
  273.             default:
  274.                 break;
  275.             }
  276.             if ((ELEM.flag & kSavedInNVRAM) != 0) {
  277.                 picHandle = GetPicture(PICT_InNVRAM);
  278.                 if (picHandle != NULL)
  279.                     DrawPicture(picHandle, &pictRect);
  280.                 OffsetRect(&pictRect, pictWidth, 0);
  281.             }
  282.             if ((ELEM.flag & kSavedOnDisk) != 0) {
  283.                 picHandle = GetPicture(PICT_OnDisk);
  284.                 if (picHandle != NULL)
  285.                     DrawPicture(picHandle, &pictRect);
  286.                 OffsetRect(&pictRect, pictWidth, 0);
  287.             }
  288.             SectRect(&pictRect, viewRect, &textRect);
  289.             break;
  290.         case kValueIndentLevel:
  291.         default:
  292.             OffsetRect(&pictRect, pictWidth, 0);
  293.             SectRect(&pictRect, viewRect, &textRect);
  294.             break;
  295.         }
  296.         if (isLeftJustify)
  297.             MoveTo(textRect.left, textRect.top + info.ascent);
  298.         else {
  299.             textWidth = TextWidth(ELEM.data, 0, ELEM.dataLength);
  300.             MoveTo(textRect.right - textWidth, textRect.top + info.ascent);
  301.         }
  302.         DrawText(ELEM.data, 0, ELEM.dataLength);
  303. #undef ELEM
  304. }
  305.  
  306.